#include "Atransfer_default.h"

#if ATRANSFER_USE_UPDATA == 1
#include "stdlib.h"
#include "A_shell.h"
#include "A_transfer.h"
//extern dev_w25qxx_t m_w25q128;
static uint32_t update_file_total_size, update_file_cur_size;
static enum ym_code ymodem_on_begin(struct ym_ctx *ctx, uint8_t *buf, uint32_t len)
{
    char *file_name, *file_size;

    /* calculate and store file size */
    file_name = (char *)&buf[0];
    file_size = (char *)&buf[strlen(file_name) + 1];
    update_file_total_size = atol(file_size);
    update_file_cur_size = 0;

    if (update_file_total_size > ATRANSFER_FLASH_AREA_SIZE)
        return YM_CODE_CAN;
    /* erase backup section */
    ATRANSFER_FLASH_ERASE_FUN(ATRANSFER_FLASH_START_ADDR, update_file_total_size);
    return YM_CODE_ACK;
}

static enum ym_code ymodem_on_data(struct ym_ctx *ctx, uint8_t *buf, uint32_t len)
{

    if ((update_file_cur_size + len) > update_file_total_size)
        len = update_file_total_size - update_file_cur_size;
    /* write data of application to backup section  */
    ATRANSFER_FLASH_WRITE_FUN(buf, update_file_cur_size, len);

    update_file_cur_size += len;
    if (update_file_cur_size > update_file_total_size)
        return YM_CODE_CAN;

    return YM_CODE_ACK;
}

/**
 * update command for RT-Thread finsh-msh command.
 */
int A_update(void)
{
    int err;
    struct ym_ctx rctx;
    Ashell_print("Please select a update file and use Ymodem to send.\r\n");

    err = ym_recv_on_device(&rctx, ymodem_on_begin, ymodem_on_data, NULL, 100);
    if (!err)
    {
        Ashell_print("Update user app succes.\r\n");
        ATRANSFER_SYSTEM_RESET_FUN();
    }
    else
    {
        Ashell_print("Update user app fail.\r\n");
    }
    return err;
}
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC), updata, A_update, update the application);
#endif
